import React, {useEffect, useState} from 'react';
import {Menu} from 'antd';
import {Link} from 'react-router-dom';
import {DragDropContext, Draggable, Droppable} from "react-beautiful-dnd";
import {Menu as RoutesMenu} from '../../routes/manage.config';
import {MenuProps} from 'antd/lib/menu';
import {MenuInfo} from "rc-menu/lib/interface";

/**
 * 单个路由菜单
 */
const renderMenuItem = (item: RoutesMenu) => {
    const {iconComponent: IconComponent, path, query, title} = item;

    return (
        <Menu.Item key={path}>
            <Link to={path + (query || '')}>
                {IconComponent ? <IconComponent/> : <></>}
                <span>{title}</span>
            </Link>
        </Menu.Item>
    );
}

/**
 * 渲染子菜单
 */
const renderSubMenu = (item: RoutesMenu) => {
    const {iconComponent: IconComponent, path, title} = item;
    return (
        <Menu.SubMenu
            key={path}
            title={
                <span>
                   {IconComponent ? <IconComponent/> : <></>}
                    <span>{title}</span>
                </span>
            }
        >
            {item.subs!.map((sub) => (sub.subs ? renderSubMenu(sub) : renderMenuItem(sub)))}
        </Menu.SubMenu>
    );
};

type SiderMenuProps = MenuProps & {

    /**
     * 路由菜单项
     */
    menus: RoutesMenu[];

    /**
     * 菜单项点击事件
     * @param e
     */
    onClick: (e: MenuInfo) => void;

    /**
     * 选中的菜单键
     */
    selectedKeys: string[];
};

/**
 * 页面菜单栏
 */
const SiderMenu = ({menus, ...props}: SiderMenuProps) => {
    const [dragItems, setDragItems] = useState<RoutesMenu[]>([]);

    useEffect(() => {
        setDragItems(menus);
    }, [menus]);

    /**
     * 重新排序
     */
    const reorder = (list: RoutesMenu[], startIndex: number, endIndex: number): RoutesMenu[] => {
        const result = Array.from(list);
        const [removed] = result.splice(startIndex, 1);
        result.splice(endIndex, 0, removed);
        return result;
    };

    const onDragEnd = (result: any) => {
        // 被排除在名单之外
        if (!result.destination) {
            return;
        }

        const _items = reorder(dragItems, result.source.index, result.destination.index);
        setDragItems(_items);
    };

    return (
        <DragDropContext onDragEnd={onDragEnd}>
            <Droppable droppableId="droppable">
                {(provided, snapshot) => (
                    <div ref={provided.innerRef} {...provided.droppableProps}>
                        {dragItems.map((item: RoutesMenu, index: number) => (
                            <Draggable key={item.path} draggableId={item.path} index={index}>
                                {(provided, snapshot) => (
                                    <div
                                        ref={provided.innerRef}
                                        {...provided.draggableProps}
                                        {...provided.dragHandleProps}
                                        onDragStart={(e: React.DragEvent<any>) =>
                                            provided.dragHandleProps &&
                                            provided.dragHandleProps.onDragStart(e as any)
                                        }
                                    >
                                        <Menu {...props}>
                                            {item.subs! ? renderSubMenu(item) : renderMenuItem(item)}
                                        </Menu>
                                    </div>
                                )}
                            </Draggable>
                        ))}
                        {provided.placeholder}
                    </div>
                )}
            </Droppable>
        </DragDropContext>
    );
};

export default React.memo(SiderMenu);
